home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap14 / GrafMenu / GrafMenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  9.4 KB  |  298 lines

  1. /*----------------------------------------------
  2.    GRAFMENU.C -- Demonstrates Bitmap Menu Items
  3.                  (c) Charles Petzold, 1998
  4.   ----------------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include "resource.h"
  8.  
  9. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  10. void    AddHelpToSys     (HINSTANCE, HWND) ;
  11. HMENU   CreateMyMenu     (HINSTANCE) ;
  12. HBITMAP StretchBitmap    (HBITMAP) ;
  13. HBITMAP GetBitmapFont    (int) ;
  14. void    DeleteAllBitmaps (HWND) ;
  15.  
  16. TCHAR szAppName[] = TEXT ("GrafMenu") ;
  17.  
  18. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  19.                     PSTR szCmdLine, int iCmdShow)
  20. {
  21.      HWND     hwnd ;
  22.      MSG      msg ;
  23.      WNDCLASS wndclass ;
  24.      
  25.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  26.      wndclass.lpfnWndProc   = WndProc ;
  27.      wndclass.cbClsExtra    = 0 ;
  28.      wndclass.cbWndExtra    = 0 ;
  29.      wndclass.hInstance     = hInstance ;
  30.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  31.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  32.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  33.      wndclass.lpszMenuName  = NULL ;
  34.      wndclass.lpszClassName = szAppName ;
  35.      
  36.      if (!RegisterClass (&wndclass))
  37.      {
  38.           MessageBox (NULL, TEXT ("This program requires Windows NT!"),
  39.                       szAppName, MB_ICONERROR) ;
  40.           return 0 ;
  41.      }
  42.      
  43.      hwnd = CreateWindow (szAppName, TEXT ("Bitmap Menu Demonstration"),
  44.                           WS_OVERLAPPEDWINDOW,
  45.                           CW_USEDEFAULT, CW_USEDEFAULT,
  46.                           CW_USEDEFAULT, CW_USEDEFAULT,
  47.                           NULL, NULL, hInstance, NULL) ;
  48.      
  49.      ShowWindow (hwnd, iCmdShow) ;
  50.      UpdateWindow (hwnd) ;
  51.      
  52.      while (GetMessage (&msg, NULL, 0, 0))
  53.      {
  54.           TranslateMessage (&msg) ;
  55.           DispatchMessage (&msg) ;
  56.      }
  57.      return msg.wParam ;
  58. }
  59.  
  60. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  61. {
  62.      HMENU      hMenu ;
  63.      static int iCurrentFont = IDM_FONT_COUR ;
  64.      
  65.      switch (iMsg)
  66.      {
  67.      case WM_CREATE:
  68.           AddHelpToSys (((LPCREATESTRUCT) lParam)->hInstance, hwnd) ;
  69.           hMenu = CreateMyMenu (((LPCREATESTRUCT) lParam)->hInstance) ;
  70.           SetMenu (hwnd, hMenu) ;
  71.           CheckMenuItem (hMenu, iCurrentFont, MF_CHECKED) ;
  72.           return 0 ;
  73.           
  74.      case WM_SYSCOMMAND:
  75.           switch (LOWORD (wParam))
  76.           {
  77.           case IDM_HELP:
  78.                MessageBox (hwnd, TEXT ("Help not yet implemented!"),
  79.                            szAppName, MB_OK | MB_ICONEXCLAMATION) ;
  80.                return 0 ;
  81.           }
  82.           break ;
  83.           
  84.      case WM_COMMAND:
  85.           switch (LOWORD (wParam))
  86.           {
  87.           case IDM_FILE_NEW:
  88.           case IDM_FILE_OPEN:
  89.           case IDM_FILE_SAVE:
  90.           case IDM_FILE_SAVE_AS:
  91.           case IDM_EDIT_UNDO:
  92.           case IDM_EDIT_CUT:
  93.           case IDM_EDIT_COPY:
  94.           case IDM_EDIT_PASTE:
  95.           case IDM_EDIT_CLEAR:
  96.                MessageBeep (0) ;
  97.                return 0 ;
  98.                     
  99.           case IDM_FONT_COUR:
  100.           case IDM_FONT_ARIAL:
  101.           case IDM_FONT_TIMES:
  102.                hMenu = GetMenu (hwnd) ;
  103.                CheckMenuItem (hMenu, iCurrentFont, MF_UNCHECKED) ;
  104.                iCurrentFont = LOWORD (wParam) ;
  105.                CheckMenuItem (hMenu, iCurrentFont, MF_CHECKED) ;
  106.                return 0 ;
  107.           }
  108.           break ;
  109.                
  110.      case WM_DESTROY:
  111.           DeleteAllBitmaps (hwnd) ;
  112.           PostQuitMessage (0) ;
  113.           return 0 ;
  114.      }
  115.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  116. }
  117.  
  118. /*----------------------------------------------------
  119.    AddHelpToSys: Adds bitmap Help item to system menu
  120.   ----------------------------------------------------*/
  121.  
  122. void AddHelpToSys (HINSTANCE hInstance, HWND hwnd)
  123. {
  124.      HBITMAP hBitmap ;
  125.      HMENU   hMenu ;
  126.  
  127.      hMenu = GetSystemMenu (hwnd, FALSE);
  128.      hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapHelp"))) ;
  129.      AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
  130.      AppendMenu (hMenu, MF_BITMAP, IDM_HELP, (PTSTR) (LONG) hBitmap) ;
  131. }
  132.  
  133. /*----------------------------------------------
  134.    CreateMyMenu: Assembles menu from components
  135.   ----------------------------------------------*/
  136.  
  137. HMENU CreateMyMenu (HINSTANCE hInstance)
  138. {
  139.      HBITMAP hBitmap ;
  140.      HMENU   hMenu, hMenuPopup ;
  141.      int     i ;
  142.  
  143.      hMenu = CreateMenu () ;
  144.      
  145.      hMenuPopup = LoadMenu (hInstance, TEXT ("MenuFile")) ;
  146.      hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFile"))) ;
  147.      AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup,
  148.                         (PTSTR) (LONG) hBitmap) ;
  149.      
  150.      hMenuPopup = LoadMenu (hInstance, TEXT ("MenuEdit")) ;
  151.      hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapEdit"))) ;
  152.      AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup,
  153.                         (PTSTR) (LONG) hBitmap) ;
  154.      
  155.      hMenuPopup = CreateMenu () ;
  156.      
  157.      for (i = 0 ; i < 3 ; i++)
  158.      {
  159.           hBitmap = GetBitmapFont (i) ;
  160.           AppendMenu (hMenuPopup, MF_BITMAP, IDM_FONT_COUR + i, 
  161.                                   (PTSTR) (LONG) hBitmap) ;
  162.      }
  163.      
  164.      hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFont"))) ;
  165.      AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup,
  166.                         (PTSTR) (LONG) hBitmap) ;
  167.      return hMenu ;
  168. }
  169.  
  170. /*----------------------------------------------------
  171.    StretchBitmap: Scales bitmap to display resolution
  172.   ----------------------------------------------------*/
  173.  
  174. HBITMAP StretchBitmap (HBITMAP hBitmap1)
  175. {
  176.      BITMAP     bm1, bm2 ;
  177.      HBITMAP    hBitmap2 ;
  178.      HDC        hdc, hdcMem1, hdcMem2 ;
  179.      int        cxChar, cyChar ;
  180.  
  181.           // Get the width and height of a system font character
  182.  
  183.      cxChar = LOWORD (GetDialogBaseUnits ()) ;
  184.      cyChar = HIWORD (GetDialogBaseUnits ()) ;
  185.  
  186.           // Create 2 memory DCs compatible with the display
  187.      
  188.      hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;
  189.      hdcMem1 = CreateCompatibleDC (hdc) ;
  190.      hdcMem2 = CreateCompatibleDC (hdc) ;
  191.      DeleteDC (hdc) ;
  192.  
  193.           // Get the dimensions of the bitmap to be stretched
  194.      
  195.      GetObject (hBitmap1, sizeof (BITMAP), (PTSTR) &bm1) ;
  196.  
  197.           // Scale these dimensions based on the system font size
  198.      
  199.      bm2 = bm1 ;
  200.      bm2.bmWidth      = (cxChar * bm2.bmWidth)  / 4 ;
  201.      bm2.bmHeight     = (cyChar * bm2.bmHeight) / 8 ;
  202.      bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2 ;
  203.  
  204.           // Create a new bitmap of larger size
  205.      
  206.      hBitmap2 = CreateBitmapIndirect (&bm2) ;
  207.  
  208.           // Select the bitmaps in the memory DCs and do a StretchBlt
  209.      
  210.      SelectObject (hdcMem1, hBitmap1) ;
  211.      SelectObject (hdcMem2, hBitmap2) ;
  212.      
  213.      StretchBlt (hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight,
  214.                  hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ;
  215.  
  216.           // Clean up
  217.      
  218.      DeleteDC (hdcMem1) ;
  219.      DeleteDC (hdcMem2) ;
  220.      DeleteObject (hBitmap1) ;
  221.      
  222.      return hBitmap2 ;
  223. }
  224.  
  225. /*------------------------------------------------
  226.    GetBitmapFont: Creates bitmaps with font names
  227.   ------------------------------------------------*/
  228.  
  229. HBITMAP GetBitmapFont (int i)
  230. {
  231.      static TCHAR  * szFaceName[3] = { TEXT ("Courier New"), TEXT ("Arial"), 
  232.                                        TEXT ("Times New Roman") } ;
  233.      HBITMAP         hBitmap ;
  234.      HDC             hdc, hdcMem ;
  235.      HFONT           hFont ;
  236.      SIZE            size ;
  237.      TEXTMETRIC      tm ;
  238.      
  239.      hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;
  240.      GetTextMetrics (hdc, &tm) ;
  241.      
  242.      hdcMem = CreateCompatibleDC (hdc) ;
  243.      hFont  = CreateFont (2 * tm.tmHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  244.                           szFaceName[i]) ;
  245.  
  246.      hFont = (HFONT) SelectObject (hdcMem, hFont) ;
  247.      GetTextExtentPoint32 (hdcMem, szFaceName[i], 
  248.                            lstrlen (szFaceName[i]), &size);
  249.      
  250.      hBitmap = CreateBitmap (size.cx, size.cy, 1, 1, NULL) ;
  251.      SelectObject (hdcMem, hBitmap) ;
  252.      
  253.      TextOut (hdcMem, 0, 0, szFaceName[i], lstrlen (szFaceName[i])) ;
  254.      
  255.      DeleteObject (SelectObject (hdcMem, hFont)) ;
  256.      DeleteDC (hdcMem) ;
  257.      DeleteDC (hdc) ;
  258.      
  259.      return hBitmap ;
  260. }
  261.  
  262. /*------------------------------------------------------- 
  263.    DeleteAllBitmaps: Deletes all the bitmaps in the menu
  264.   -------------------------------------------------------*/
  265.  
  266. void DeleteAllBitmaps (HWND hwnd)
  267. {
  268.      HMENU        hMenu ;
  269.      int          i ;
  270.      MENUITEMINFO mii = { sizeof (MENUITEMINFO), MIIM_SUBMENU | MIIM_TYPE } ;
  271.  
  272.           // Delete Help bitmap on system menu
  273.  
  274.      hMenu = GetSystemMenu (hwnd, FALSE);
  275.      GetMenuItemInfo (hMenu, IDM_HELP, FALSE, &mii) ;
  276.      DeleteObject ((HBITMAP) mii.dwTypeData) ;
  277.  
  278.           // Delete top-level menu bitmaps
  279.  
  280.      hMenu = GetMenu (hwnd) ;
  281.  
  282.      for (i = 0 ; i < 3 ; i++)
  283.      {
  284.           GetMenuItemInfo (hMenu, i, TRUE, &mii) ;
  285.           DeleteObject ((HBITMAP) mii.dwTypeData) ;
  286.      }
  287.  
  288.           // Delete bitmap items on Font menu
  289.  
  290.      hMenu = mii.hSubMenu ;;
  291.  
  292.      for (i = 0 ; i < 3 ; i++)
  293.      {
  294.           GetMenuItemInfo (hMenu, i, TRUE, &mii) ;
  295.           DeleteObject ((HBITMAP) mii.dwTypeData) ;
  296.      }
  297. }
  298.